package com.jsd.openapi.handler;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;

import java.security.KeyPair;

/**
 * 加密/解密处理器
 */
public interface EncryptDecryptHandler {

    /**
     * 生成密钥对
     *
     * @return
     */
    KeyPair generateKeyPair();

    /**
     * 获取公钥
     *
     * @param keyPair 密钥对
     * @return
     */
    default String getPublicKey(KeyPair keyPair) {
        return Base64Encoder.encode(keyPair.getPublic().getEncoded());
    }

    /**
     * 获取私钥
     *
     * @param keyPair 密钥对
     * @return
     */
    default String getPrivateKey(KeyPair keyPair) {
        return Base64Encoder.encode(keyPair.getPrivate().getEncoded());
    }

    /**
     * 加密明文
     *
     * @param object    对象
     * @param publicKey 公钥
     * @return
     */
    String encryptByPublicKey(Object object, String publicKey);

    /**
     * 加密明文
     *
     * @param object     对象
     * @param privateKey 私钥
     * @return
     */
    String encryptByPrivateKey(Object object, String privateKey);

    /**
     * 解密密文
     *
     * @param encryptText 密文文本
     * @param publicKey   公钥
     * @return
     */
    String decryptByPublicKey(String encryptText, String publicKey);

    /**
     * 解密密文
     *
     * @param encryptText 密文文本
     * @param publicKey   公钥
     * @param clazz       解密类型
     * @param <T>         泛型
     * @return
     */
    default <T> T decryptByPublicKey(String encryptText, String publicKey, Class<T> clazz) {
        String plainText = this.decryptByPublicKey(encryptText, publicKey);
        return JSONUtil.toBean(plainText, clazz);
    }

    /**
     * 解密密文
     *
     * @param encryptText   密文文本
     * @param publicKey     公钥
     * @param typeReference 解密类型
     * @param <T>           泛型
     * @return
     */
    default <T> T decryptByPublicKey(String encryptText, String publicKey, TypeReference<T> typeReference) {
        String plainText = this.decryptByPublicKey(encryptText, publicKey);
        return JSONUtil.toBean(plainText, typeReference, true);
    }

    /**
     * 解密密文
     *
     * @param encryptText 密文文本
     * @param privateKey  私钥
     * @return
     */
    String decryptByPrivateKey(String encryptText, String privateKey);

    /**
     * 解密密文
     *
     * @param encryptText 密文文本
     * @param privateKey  私钥
     * @param clazz       解密类型
     * @param <T>         泛型
     * @return
     */
    default <T> T decryptByPrivateKey(String encryptText, String privateKey, Class<T> clazz) {
        String plainText = this.decryptByPrivateKey(encryptText, privateKey);
        return JSONUtil.toBean(plainText, clazz);
    }

    /**
     * 解密密文
     *
     * @param encryptText   密文文本
     * @param privateKey    私钥
     * @param typeReference 解密类型
     * @param <T>           泛型
     * @return
     */
    default <T> T decryptByPrivateKey(String encryptText, String privateKey, TypeReference<T> typeReference) {
        String plainText = this.decryptByPrivateKey(encryptText, privateKey);
        return JSONUtil.toBean(plainText, typeReference, true);
    }

}
